//
// AWS Manager - A free AWS console application demonstrating advanced concepts
// Copyright (C) 2008-2010 Sean O'Dell. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package com.awsmanager.common;

import com.sun.data.provider.RowKey;
import com.sun.data.provider.impl.ObjectListDataProvider;
import com.xerox.amazonws.sdb.Domain;
import com.xerox.amazonws.sdb.Item;
import com.xerox.amazonws.sdb.ItemAttribute;
import com.xerox.amazonws.sdb.QueryWithAttributesResult;
import com.xerox.amazonws.sdb.SDBException;
import com.xerox.amazonws.sdb.SimpleDB;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Sean ODell
 */
public class SDBItemDataProvider extends ObjectListDataProvider {

    private List<SDBItem> sdbItemList = new ArrayList<SDBItem>();
    private SimpleDB simpleDB;
    private Domain sdbdomain = null;

    public SDBItemDataProvider() {
        setList(sdbItemList);
        setObjectType(SDBItem.class);
    }

    public void load(SDBConnection sdbconnection, Map dataproviders) {

        clearObjectList();

        QueryWithAttributesResult queryResult = null;
        String sdbdomainname = null;
        boolean hasMoreItems = true;

        Map<String, List<ItemAttribute>> itemListInput = null;
        List<ItemAttribute> itemAttributeList = null;

        List<String> itemListStr = new ArrayList<String>();
        Map<String, List<ItemAttribute>> itemList = new HashMap<String, List<ItemAttribute>>();

        if (sdbconnection == null) {
            return;
        }

        if ((simpleDB = sdbconnection.getsimpleDB()) != null) {

            sdbdomainname = sdbconnection.getsdbdomain();

            try {
                sdbdomain = simpleDB.getDomain(sdbdomainname);
            } catch (SDBException ex) {
                sdbdomain = null;
                Logger.getLogger(EBSVolumeDataProvider.class.getName()).log(Level.SEVERE, null, ex);
            }

            if (sdbdomain != null) {
                try {
                    queryResult = sdbdomain.selectItems("select * from " + sdbdomainname, null);
                } catch (SDBException ex) {
                    Logger.getLogger(SDBItemDataProvider.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

            if (queryResult != null) {

                itemListInput = queryResult.getItems();

                while (hasMoreItems && (itemListInput != null)) {

                    for (String id : itemListInput.keySet()) {
                        itemAttributeList = itemListInput.get(id);
                        itemList.put(id, itemListInput.get(id));
                        itemListStr.add(id);
                    }

                    if (queryResult.getNextToken() != null) {
                        try {
                            queryResult = sdbdomain.selectItems("select * from " + sdbdomainname, queryResult.getNextToken());
                            itemListInput = queryResult.getItems();
                        } catch (SDBException ex) {
                            Logger.getLogger(SDBItemDataProvider.class.getName()).log(Level.SEVERE, null, ex);
                            itemListInput = null;
                        }
                    } else {
                        hasMoreItems = false;
                    }
                }

                Collections.sort(itemListStr);
                for (String itemid : itemListStr) {

                    SDBItem sdbItem = new SDBItem();
                    sdbItem.setId(itemid);
                    itemAttributeList = itemList.get(itemid);

                    if (itemAttributeList != null) {
                        for (ItemAttribute itemAttribute : itemAttributeList) {
                            if (itemAttribute.getName().equals("type")) {
                                sdbItem.setType(itemAttribute.getValue());
                               sdbItem.setState(getItemState(itemid,
                                        itemAttribute.getValue(), dataproviders));
                            } else if (itemAttribute.getName().equals("name")) {
                                sdbItem.setName(itemAttribute.getValue());
                            } else if (itemAttribute.getName().equals("ownernamelast")) {
                                sdbItem.setOwnernamelast(itemAttribute.getValue());
                            } else if (itemAttribute.getName().equals("ownernamefirst")) {
                                sdbItem.setOwnernamefirst(itemAttribute.getValue());
                            } else if (itemAttribute.getName().equals("ownerdept")) {
                                sdbItem.setOwnerdept(itemAttribute.getValue());
                            } else if (itemAttribute.getName().equals("createtime")) {
                                sdbItem.setCreatetime(itemAttribute.getValue());
                            } else if (itemAttribute.getName().equals("description")) {
                                sdbItem.setDescription(itemAttribute.getValue());
                            }
                        }
                    }
                    getList().add(sdbItem);
                }
            }
        }
    }

    public SDBItem getSDBItem(RowKey rowKey) {
        SDBItem sdbItem = (SDBItem) getObject(rowKey);
        return sdbItem;
    }

    public SDBItem getSDBItem(String id) {
        for (int i = 0; i < sdbItemList.size(); i++) {
            SDBItem sdbItem = (SDBItem) sdbItemList.get(i);
            if (sdbItem.getId().equals(id)) {
                return sdbItem;
            }
        }
        return null;
    }

    public int getSDBItemIndex(String id) {
        for (int i = 0; i < sdbItemList.size(); i++) {
            SDBItem sdbItem = (SDBItem) sdbItemList.get(i);
            if (sdbItem.getId().equals(id)) {
                return i;
            }
        }
        return -1;
    }

    public String deleteSDBItems(RowKey[] selectedRowKeys) {
        String statusMsg = new String();
        if (sdbdomain != null) {
            for (int i = 0; i < selectedRowKeys.length; i++) {
                RowKey rowKey = selectedRowKeys[i];
                SDBItem sdbItem = getSDBItem(rowKey);
                try {
                    sdbdomain.deleteItem(sdbItem.getId());
                    statusMsg = statusMsg + "Deleted item: " + sdbItem.getId() + "\n";
                } catch (SDBException ex) {
                    Logger.getLogger(SDBItemDataProvider.class.getName()).log(Level.SEVERE, null, ex);
                    statusMsg = statusMsg + "Error: " + ex + "\n";
                }
            }
        } else {
            statusMsg = "SDB Connection timed out. Re-load user settings.";
        }
        return statusMsg;
    }

    public String getItemState(String id, String type, Map dataproviders) {
        String state = new String("terminated");
        if (type.equals("instance")) {
            EC2InstanceDataProvider dataprovider =
                    (EC2InstanceDataProvider) dataproviders.get(type);
            EC2Instance ec2Instance = dataprovider.getInstance(id);
            if (ec2Instance != null) {
                state = ec2Instance.getstateName();
            }
        } else if (type.equals("volume")) {
            EBSVolumeDataProvider dataprovider =
                    (EBSVolumeDataProvider) dataproviders.get(type);
            EBSVolume ebsVolume = dataprovider.getVolume(id);
            if (ebsVolume != null) {
                state = ebsVolume.getvstatus();
            }
        } else if (type.equals("snapshot")) {
            EBSSnapshotDataProvider dataprovider =
                    (EBSSnapshotDataProvider) dataproviders.get(type);
            EBSSnapshot ebsSnapshot = dataprovider.getSnapshot(id);
            if (ebsSnapshot != null) {
                state = ebsSnapshot.getstatus();
            }
        } else if (type.equals("elasticip")) {
            EC2IPDataProvider dataprovider =
                    (EC2IPDataProvider) dataproviders.get(type);
            EC2IP ec2IP = dataprovider.getEC2IP(id);
            if (ec2IP != null) {
                state = "in-use";
            }
        }
        return state;
    }

    public String updateItem(Map iteminfo) {

        int itemIndex = -1;
        String statusMsg = new String();
        Item sdbitem = null;
        List<ItemAttribute> sdbattributes = new ArrayList<ItemAttribute>();

        String itemid = (String) iteminfo.get("id");

        if (sdbdomain != null) {
            try {
                sdbitem = sdbdomain.getItem(itemid);
                sdbattributes.add(new ItemAttribute("name", (String) iteminfo.get("name"), true));
                sdbattributes.add(new ItemAttribute("description", (String) iteminfo.get("desc"), true));
                sdbattributes.add(new ItemAttribute("ownernamelast", (String) iteminfo.get("ownernamelast"), true));
                sdbattributes.add(new ItemAttribute("ownernamefirst", (String) iteminfo.get("ownernamefirst"), true));
                sdbattributes.add(new ItemAttribute("ownerdept", (String) iteminfo.get("ownerdept"), true));

                sdbitem.putAttributes(sdbattributes);

                SDBItem sdbItem = getSDBItem(itemid);
                itemIndex = getSDBItemIndex(itemid);

                sdbItem.setName((String) iteminfo.get("name"));
                sdbItem.setDescription((String) iteminfo.get("desc"));
                sdbItem.setOwnernamelast((String) iteminfo.get("ownernamelast"));
                sdbItem.setOwnernamefirst((String) iteminfo.get("ownernamefirst"));
                sdbItem.setOwnerdept((String) iteminfo.get("ownerdept"));

                sdbItemList.set(itemIndex, sdbItem);

            } catch (SDBException ex) {
                Logger.getLogger(SDBItemDataProvider.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return statusMsg;
    }
}
